package archer.back.models

import java.sql.Timestamp

import io.circe._
import io.circe.syntax._
import io.circe.generic.auto._
import utils.CirceUtils

import scala.annotation.tailrec

case class NestedTreeNode(
  id: Int,
  name: String,
  modifiedTime: Timestamp,
  isParent: Boolean,
  children: List[NestedTreeNode])

object NestedTreeNode extends CirceUtils {

  implicit val dateEncoder = timestampEncoderFromPattern(
    "yyyy-MM-dd HH:mm:ss.SSS")
  implicit val dateDecoder = timestampDeocderFromPattern(
    "yyyy-MM-dd HH:mm:ss.SSS")

  implicit val encoder = implicitly[Encoder[NestedTreeNode]]
  implicit val decoder = implicitly[Decoder[NestedTreeNode]]

  import models.CrawlTables._

  def fromUpdateTreeNodeRow(list: List[UpdateTreeNodeRow]) = {
    val head = list.filter(_.parentId < 0).head
    fromUpdateTreeNodeRowGen(
      list,
      NestedTreeNode(
        id = head.id,
        name = head.name,
        modifiedTime = head.modifiedTime,
        isParent = true,
        children = List.empty))
  }
  private def fromUpdateTreeNodeRowGen(
    list: List[UpdateTreeNodeRow],
    parentNode: NestedTreeNode): NestedTreeNode = {
    /*@tailrec
    def abc(innerSubList: List[UpdateTreeNodeRow], innerParent: NestedTreeNode, subNodes: Option[NestedTreeNode]): NestedTreeNode = {
      innerSubList match {
        case Nil =>
          subNodes match {
            case Some(innerSub) =>
              innerParent.copy(children = innerParent.children ::: innerSub :: Nil)
            case _ =>
              innerParent
          }
        case l@(head :: tail )=>
          subNodes match {
            case Some(innerSub) =>
              abc(l,innerParent.copy(children = innerParent.children ::: innerSub :: Nil), Option.empty)
            case _ =>
              abc(tail,innerParent, Option(NestedTreeNode(id = head.id, name = head.name, modifiedTime = head.modifiedTime, children = List.empty)))

          }
      }
    }*/

    val subs = list.filter(s => s.parentId == parentNode.id)
    subs match {
      case Nil =>
        parentNode.copy(isParent = false)
      case children =>
        parentNode.copy(
          children = children.map(s =>
            fromUpdateTreeNodeRowGen(
              list,
              NestedTreeNode(
                id = s.id,
                name = s.name,
                //play.twirl.api.HtmlFormat.escape(s.name).body,
                modifiedTime = s.modifiedTime,
                isParent = true,
                children = List.empty))))
    }
  }

}
